package com.association.main.utils;
import com.association.main.common.CustomException;
import com.association.main.domain.Users;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
@Slf4j
public class JwtUtil {

    public static final long EXPIRE = 1000 * 60 * 60 * 24 ;
    //一天过期
    public static final String APP_SECRET = "kappy";
    public static String getJwtToken(Users user){
        String JwtToken = Jwts.builder()
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                .claim("username", user.getUsername())
                .claim("roles", user.getRole())
                .claim("id", user.getId())
                .signWith(SignatureAlgorithm.HS256, APP_SECRET)
                .compact();
        return JwtToken;
    }
    /**
     * 判断token是否存在与有效
     * @param jwtToken
     * @return
     */
    public static boolean checkToken(String jwtToken) {
        if(StringUtils.isEmpty(jwtToken)) return false;
        try {
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException("Token无效：请你重新登录"); // 抛出异常
        }
        return true;
    }
    /**
     * 判断token是否存在与有效
     * @param request
     * @return
     */
    public static String checkToken(HttpServletRequest request) {
        try {
            String jwtToken = request.getHeader("token");
            if(StringUtils.isEmpty(jwtToken)) return "error";
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
            Claims claims = claimsJws.getBody();

            // 获取token过期时间
            Date expiration = claims.getExpiration();
            Date now = new Date();
            // 如果距离过期时间只剩下5分钟，就刷新token
            if (expiration.getTime() - now.getTime() <= 5 * 60 * 1000) {
                Users user = new Users();
                user.setUsername((String) claims.get("username"));
                user.setRole((String) claims.get("roles"));
                user.setId((Integer) claims.get("id"));

                // 重新生成token并设置到response header中
                String newToken = getJwtToken(user);
                return newToken;
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
        return "error";
    }


    /**
     * 获取用户id
     */
    public static Integer getUserId(String token){
        try {
            Jws<Claims> claimsJws =
                    Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
            Claims claims = claimsJws.getBody();
            return (Integer) claims.get("id");
        } catch (Exception e) {
            throw new CustomException("Token无效：请你重新登录"); // 抛出异常
        }

    }

    /**
     * 获取用户type
     */
    public static String getUserType(String token){
        try {
            Jws<Claims> claimsJws =
                    Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
            Claims claims = claimsJws.getBody();
            return (String)   claims.get("roles");
        } catch (Exception e) {
            throw new CustomException("Token无效：请你重新登录"); // 抛出异常
        }




    }

    /**
     * 根据token获取xm
     * @return
     */
    public static String getMemberIdByJwtToken(String token) {
//        String jwtToken = request.getHeader("token");
        Jws<Claims> claimsJws =
                Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        return (String)claims.get("username");
    }



    /**
     * 获取Token过期时间
     * @param jwtToken
     * @return 过期时间的时间戳，单位毫秒
     */
    public static long getTokenExpirationTime(String jwtToken) {
        try {
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
            Claims claims = claimsJws.getBody();
            return claims.getExpiration().getTime();
        } catch (Exception e) {
            throw new CustomException("Token无效：请您重新登录");
        }
    }



}
